package com.arpa.wms.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.wms.cache.LocationCache;
import com.arpa.wms.domain.dto.PickItemCancelQuantityDto;
import com.arpa.wms.domain.dto.PickingItemDTO;
import com.arpa.wms.domain.dto.PickingRegisterDTO;
import com.arpa.wms.domain.dto.WmsTaskDTO;
import com.arpa.wms.domain.entity.PickingItem;
import com.arpa.wms.domain.enums.PickingRegisterStatusEnum;
import com.arpa.wms.domain.vo.*;
import com.arpa.wms.mapper.LocationMapper;
import com.arpa.wms.mapper.PickingItemMapper;
import com.arpa.wms.service.IGoodsPnService;
import com.arpa.wms.service.IPickingItemService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 拣货明细 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-08-07
 */
@Service
public class PickingItemServiceImpl extends ServiceImpl<PickingItemMapper, PickingItem> implements IPickingItemService {


    @Autowired
    private LocationCache locationCache;

    @Resource
    private LocationMapper locationMapper;


    @Autowired
    private IGoodsPnService goodsPnService;

    /**
     * 保存
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public boolean save(PickingItem entity) {
        if(StringUtils.isBlank(entity.getCode())){
            entity.setCode(IdUtil.simpleUUID());
        }
        entity.setGroupCode(UserUtil.getBranchCode());
        if(StringUtils.isBlank(entity.getCreatedBy())){
            entity.setCreatedBy(UserUtil.getCode());
        }
        return super.save(entity);
    }

    /**
     * 根据code更新实体
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public int updateByCode(PickingItem entity) {
        if(StringUtils.isBlank(entity.getModifiedBy())){
            entity.setModifiedBy(UserUtil.getCode());
        }
        return baseMapper.update(entity,new QueryWrapper<PickingItem>().lambda().eq(PickingItem::getCode,entity.getCode()).eq(PickingItem::getGroupCode,UserUtil.getBranchCode()));
    }

    /**
     * 查询列表
     * @param pickingItemDTO
     * @return
     */
    @Override
    public List<PickingItemVO> queryList(PickingItemDTO pickingItemDTO){
        //排序字段名需要驼峰转数据库下划线类型字段名
        if(StringUtils.isNotEmpty(pickingItemDTO.getSortField())){
            pickingItemDTO.setSortField(CommonUtil.camel2Underline(pickingItemDTO.getSortField()));
        }
        List<PickingItemVO> pickingItemVOList = baseMapper.queryList(pickingItemDTO);
        return pickingItemVOList;
    }

    /**
     * 查询合计,包含总数
     * @param pickingItemDTO
     * @return
     */
    @Override
    public PickingItemVO queryListSum(PickingItemDTO pickingItemDTO){
        PickingItemVO pickingItemVO = baseMapper.queryListSum(pickingItemDTO);
        return pickingItemVO;
    }

    /**
     * @description 查询拣货单与拣货确认单列表
     * @author xuyang
     * @date 2020/10/22 13:25
     * @param pickingItemDTO :
     **/
    @Override
    public List<PickingItemWithRegisterVO> queryItemWithRegisterList(PickingItemDTO pickingItemDTO) {
        List<PickingItemWithRegisterVO> pickingItemWithRegisterVOS = this.baseMapper.queryItemWithRegisterList(pickingItemDTO);
        return pickingItemWithRegisterVOS;
    }

    @Override
    public List<PickingItemWithRegisterVO> queryItemReturnRegisterList(PickingItemDTO pickingItemDTO) {
        List<PickingItemWithRegisterVO> pickingItemWithRegisterVOS = this.baseMapper.queryItemReturnRegisterList(pickingItemDTO);
        return pickingItemWithRegisterVOS;
    }

    /***
     * @description
     * PDA查询未拣货任务明细
     * @author xuyang
     * @date 2020/10/24 8:30
     * @param dto :
     **/
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public List<PickingTaskItemVO> queryUnPickingList(PickingRegisterDTO dto) {
        List<PickingTaskItemVO> taskItemVOS = this.baseMapper.queryUnPickingList(dto);
        // 翻译
        taskItemVOS.forEach(e->{
            e.setTaskCode(dto.getTaskCode());
            e.setSourceCode(dto.getPickingCode());
            e.setLocationName(locationCache.translate(e.getLocation()));
        });
        // 库位条件不为空，则过滤一下
        if (StrUtil.isNotBlank(dto.getLocationName())) {
            taskItemVOS = taskItemVOS.stream().filter(e -> e.getLocationName().contains(dto.getLocationName())).collect(Collectors.toList());
        }
        return taskItemVOS;
    }

    /**
     * PDA获取拣货任务详情
     *
     * @param pickingCode 拣货单号
     * @param location    拣货库位
     * @return 拣货信息
     */
    @Override
    public PickingTaskItemVO getPickingInfoForPda(String pickingCode, String location, String goodsBarCode) {

        String goodsCode = "";
        if(StrUtil.isNotBlank(goodsBarCode)){
            String shipmentCode = baseMapper.getShipmentCodeByPickingCode(pickingCode,UserUtil.getBranchCode());
            if(StrUtil.isNotBlank(shipmentCode)) {
                goodsCode = goodsPnService.getGoodsCode(shipmentCode,goodsBarCode);
            }
        }
        //如果通过pn码查到商品code,就不用商品条码查询
        if (StrUtil.isNotEmpty(goodsCode)) {
            goodsBarCode = StrUtil.EMPTY;
        }
        PickingTaskItemVO pickingTaskItemVO = baseMapper.pickingInfoForPda(pickingCode,location,goodsBarCode,goodsCode,UserUtil.getBranchCode());

        if(pickingTaskItemVO!=null){
            pickingTaskItemVO.setSourceCode(pickingCode);
            pickingTaskItemVO.setLocationName(locationCache.translate(location));
        }

        return pickingTaskItemVO;
    }


    /***
     * @description
     * PDA查询已拣货任务明细， 这个数据是从拣货确认表中查询的，为了便于与未拣货的一起管理，所以放在item这里
     * @author xuyang
     * @date 2020/10/24 8:30
     * @param dto :
     **/
    @Override
    public List<PickingTaskItemVO> queryFinishPickingList(WmsTaskDTO dto) {
        String status = PickingRegisterStatusEnum.FINISH_PICKING.getValue();
        dto.setStatus(status);
        String goodsCode = "";
        if(StrUtil.isNotBlank(dto.getGoodsBarCode())){
            String shipmentCode = baseMapper.getShipmentCodeByPickingCode(dto.getSourceCode(),UserUtil.getBranchCode());
            if(StrUtil.isNotBlank(shipmentCode)) {
                goodsCode = goodsPnService.getGoodsCode(shipmentCode,dto.getGoodsBarCode());
                dto.setGoodsCode(goodsCode);
            }
        }
        List<PickingTaskItemVO> taskItemVOS = this.baseMapper.queryFinishPickingList(dto);
        // 翻译
        taskItemVOS.forEach(e->{
            e.setTaskCode(dto.getCode());
            e.setSourceCode(dto.getSourceCode());
            e.setLocationName(locationCache.translate(e.getLocation()));
        });
        // 库位条件不为空，则过滤一下
        if (StrUtil.isNotBlank(dto.getLocationName())) {
            taskItemVOS = taskItemVOS.stream().filter(e -> e.getLocationName().contains(dto.getLocationName())).collect(Collectors.toList());
        }
        return taskItemVOS;
    }

    /**
     * @param pickingItemCode :
     * @param finishStatus
     * @description 尝试更新子单状态，试探明细是否完成拣货
     * @author xuyang
     * @date 2020/10/26 10:16
     **/
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateStatusIfFinish(String pickingItemCode, String finishStatus) {
        return this.baseMapper.updateStatusIfFinish(pickingItemCode, finishStatus);
    }

    /**
     * @param pickingItemCode  :
     * @param stockoutQuantity :
     * @description 更新子单缺货量
     * @author xuyang
     * @date 2020/10/26 14:08
     **/
    @Override
    public int updateStockout(String pickingItemCode, BigDecimal stockoutQuantity) {
        return this.baseMapper.updateStockout(pickingItemCode, stockoutQuantity);
    }

    /***
     * @description
     * 根据库位名称查询获取库位编码，拼接成字符串
     * @author xuyang
     * @date 2020/10/24 9:24
     * @param locationName:
     **/
    public String getLocationsByName(String warehouseCode, String locationName){
        String locationsStr = "";
        if(StrUtil.isNotBlank(locationName)) {
            Map<String,Object> map = new HashMap<>();
            map.put("warehouseCode",warehouseCode);
            map.put("serialNumber",locationName);
            List<LocationVO> locationVOs = this.locationMapper.getAllByMap(map);
            locationsStr = locationVOs.stream().map(e -> StrUtil.wrap(e.getCode(), "'")).collect(Collectors.joining(","));
        }
        return locationsStr;
    }

    /**
     * 批量更新拣货明细取消数量
     *
     *
     * @param pickItemCancelQuantityDtoList@author liuxr
     * @date 2021/5/17 21:00
     */
    @Override
    public void updateCancelQuantityBatch(List<PickItemCancelQuantityDto> pickItemCancelQuantityDtoList) {
        this.baseMapper.updateCancelQuantityBatch(pickItemCancelQuantityDtoList);
    }

    /**
     * 按单拣货，更新拣货明细拣货数量、缺货数量及拣货状态拣货完成
     *
     * @param pickingItems
     * @author liuxr
     * @date 2021/5/27 20:36
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void singlePickingUpdateItemPickingQuantityAndStockoutQuantity(List<PickingItem> pickingItems) {
        this.baseMapper.singlePickingUpdateItemPickingQuantityAndStockoutQuantity(pickingItems);
    }

    /**
     * 通过拣货单号获取入驻商标识
     * @author liuxr
     * @date 2021/8/25 14:42
     * @param pickingCode
     * @return java.lang.String
     */
    @Override
    public String getShipmentCodeByPickingCode(String pickingCode,String groupCode){
        return this.baseMapper.getShipmentCodeByPickingCode(pickingCode,groupCode);
    }

    /**
     * 获取拣货确认列表
     * @author rfwang
     * @date 2022/1/27 10:13
     * @param registerDTO
     * @return
     */
    @Override
    public List<PdaPickingRegisterVO> pickingItemList(PickingRegisterDTO registerDTO){
        return this.baseMapper.pickingItemList(registerDTO);
    }


}
